home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ue312src.zip
/
OS2NPM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-20
|
21KB
|
813 lines
/*
* OS2NONPM.C
*
* The routines in this file provide video and keyboard support using the
* OS/2 Vio and Kbd functions (not the presentation manager).
*
* The os2putc, os2eeol and os2eeop routines modify the logical video
* buffer. Os2flush calls VioShowBuf to update the physical video buffer.
* An earlier version used VioWrtTTy with ANSI processing (easy to do, but
* sloooow). A later version using VioWrtNCell was better, but not as
* good as manipulating the logical buffer.
*/
#define INCL_BASE
#include <os2.h>
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#undef PASCAL
#undef NEAR
#undef HIBYTE
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#if OS2NPM
/*
* Os2def.h defines COLOR, but no MSC stuff needs it.
* We need COLOR as defined in estruct.h, so edit it out of os2def.h.
*/
#include <conio.h>
#define NROW 102 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 100 /* # times thru update to pause */
#define CDCGA 0 /* color graphics adapter */
#define CDMONO 1 /* monochrome display adapter */
#define CDEGA 2 /* EGA */
#define CDVGA 3 /* VGA */
#define NDRIVE 4 /* number of video modes */
int dtype = -1; /* current video mode */
char drvname[][8] = { /* names of video modes */
"CGA", "MONO", "EGA", "VGA"
};
/* Forward references. */
PASCAL NEAR os2move();
PASCAL NEAR os2eeol();
PASCAL NEAR os2eeop();
PASCAL NEAR os2beep();
PASCAL NEAR os2open();
PASCAL NEAR os2close();
PASCAL NEAR os2getc();
PASCAL NEAR os2putc();
PASCAL NEAR os2flush();
PASCAL NEAR os2rev();
PASCAL NEAR os2kclose();
PASCAL NEAR os2kopen();
PASCAL NEAR os2cres();
PASCAL NEAR os2parm();
#if COLOR
PASCAL NEAR os2fcol();
PASCAL NEAR os2bcol();
#endif
struct { /* Current screen attribute for ORing */
BYTE filler; /* with character to be displayed. */
BYTE attr;
} os2cell = {0, 0x07};
struct { /* Current reverse screen attribute for */
BYTE filler; /* ORing with character to be displayed.*/
BYTE attr;
} os2rcell = {0, 0x07};
static struct { /* initial states */
USHORT ansiState; /* ANSI translation */
VIOCONFIGINFO vioConfigInfo; /* video configuration */
VIOMODEINFO vioModeInfo; /* video mode */
KBDINFO kbdInfo; /* keyboard info */
} initial;
static int cfcolor = -1; /* current foreground color */
static int cbcolor = -1; /* current background color */
static int ctrans[] = /* ansi to ibm color translation table */
{0, 4, 2, 6, 1, 5, 3, 7,
8, 12, 10, 14, 9, 13, 11, 15};
static short os2row; /* current cursor row */
static short os2col; /* current cursor col */
int revflag = FALSE; /* are we currently in rev video? */
/*
* To minimize the amount of buffer that VioShowBuf has to update, we
* keep track of the lowest and highest bytes in the logical video
* buffer which have been modified.
*/
static USHORT *lvb; /* logical video buffer */
static USHORT lvbLen; /* length of buffer */
static USHORT lvbMin; /* min index of modified byte */
static USHORT lvbMax; /* max index of modified byte */
/*
* Standard terminal interface dispatch table.
*/
TERM term = {
NROW-1,
NROW-1,
NCOL,
NCOL,
0, 0,
MARGIN,
SCRSIZ,
NPAUSE,
os2open,
os2close,
os2kopen,
os2kclose,
os2getc,
os2putc,
os2flush,
os2move,
os2eeol,
os2eeop,
os2eeop,
os2beep,
os2rev,
os2cres
#if COLOR
, os2fcol,
os2bcol
#endif
};
#if MOUSE
/* Mousing global variable */
static int mexist; /* is the mouse driver installed? */
static int nbuttons; /* number of buttons on the mouse */
static int oldbut; /* Previous state of mouse buttons */
static int oldcol; /* previous x position of mouse */
static int oldrow; /* previous y position of mouse */
HMOU mouse_handle; /* handle to opened mouse */
#endif
/* input buffers and pointers */
#define IBUFSIZE 64 /* this must be a power of 2 */
unsigned char in_buf[IBUFSIZE]; /* input character buffer */
int in_next = 0; /* pos to retrieve next input character */
int in_last = 0; /* pos to place most recent input character */
in_init() /* initialize the input buffer */
{
in_next = in_last = 0;
}
in_check() /* is the input buffer non-empty? */
{
if (in_next == in_last)
return(FALSE);
else
return(TRUE);
}
in_put(event)
int event; /* event to enter into the input buffer */
{
in_buf[in_last++] = event;
in_last &= (IBUFSIZE - 1);
}
int in_get() /* get an event from the input buffer */
{
register int event; /* event to return */
event = in_buf[in_next++];
in_next &= (IBUFSIZE - 1);
return(event);
}
#if COLOR
/*----------------------------------------------------------------------*/
/* os2fcol() */
/* Set the current foreground color. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2fcol(
int color) /* color to set */
{
if (dtype != CDMONO)
cfcolor = ctrans[color];
else
cfcolor = 7;
/* set the normal attribute */
os2cell.attr &= 0xF0;
os2cell.attr |= cfcolor;
/* set the reverse attribute */
os2rcell.attr &= 0x07;
os2rcell.attr |= cfcolor << 4;
}
/*----------------------------------------------------------------------*/
/* os2bcol() */
/* Set the current background color. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2bcol(
int color) /* color to set */
{
if (dtype != CDMONO)
cbcolor = ctrans[color];
else
cbcolor = 0;
/* set normal background attribute */
os2cell.attr &= 0x0F;
os2cell.attr |= cbcolor << 4;
/* set reverse background attribute */
os2rcell.attr &= 0x70;
os2rcell.attr |= cbcolor;
}
#endif
/*----------------------------------------------------------------------*/
/* os2move() */
/* Move the cursor. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2move(
int row,
int col)
{
os2row = row;
os2col = col;
VioSetCurPos(os2row, os2col, 0);
}
/*----------------------------------------------------------------------*/
/* os2flush() */
/* Update the physical video buffer from the logical video buffer. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2flush(void)
{
if (lvbMin <= lvbMax) { /* did anything change? */
VioShowBuf(lvbMin * 2, (lvbMax - lvbMin + 1) * 2, 0);
VioSetCurPos(os2row, os2col, 0);
}
lvbMin = lvbLen;
lvbMax = 0;
}
/*----------------------------------------------------------------------*/
/* os2char() */
/* Get a character from the keyboard. */
/* Function keys, editing keys and alt- keys queue extra bytes into */
/* input queue.
/*----------------------------------------------------------------------*/
PASCAL NEAR os2char()
{
register c; /* extended key code for special keys */
KBDKEYINFO keyInfo;
KbdCharIn(&keyInfo, IO_WAIT, 0); /* get a character */
/* Function, edit or alt- key? */
if (keyInfo.chChar == 0 || keyInfo.chChar == 0xE0) {
c = extcode(keyInfo.chScan); /* hold on to scan code */
in_put(c >> 8); /* queue up prefix byte */
in_put(c & 0xFF); /* queue up event byte */
return(0);
}
return(keyInfo.chChar & 255);
}
/*
* Read a character from the terminal, performing no editing and doing no echo
* at all. Also mouse events are forced into the input stream here.
*/
PASCAL NEAR os2getc()
{
register int c; /* character read */
#if MOUSE
NOPTRRECT mouse_rect;
#endif
os2flush();
ttc: /* return any keystrokes waiting in the
type ahead buffer */
if (in_check())
return(in_get());
#if TYPEAH
if (typahead())
return(os2char());
/* with no mouse, this is a simple get char routine */
if (mexist == FALSE || mouseflag == FALSE)
return(os2char());
#if MOUSE
/* turn the mouse cursor on */
MouDrawPtr(mouse_handle);
/* loop waiting for something to happen */
while (TRUE) {
if (typahead())
break;
if (checkmouse())
break;
DosSleep(10L); /* let others have some CPU! */
}
/* turn the mouse cursor back off */
mouse_rect.row = 0;
mouse_rect.col = 0;
mouse_rect.cRow = 24;
mouse_rect.cCol = 79;
MouRemovePtr(&mouse_rect, mouse_handle);
goto ttc;
#endif /* MOUSE */
#else /* TYPEAH */
return(os2char());
#endif /* TYPEAH */
}
#if MOUSE
checkmouse()
{
register int k; /* current bit/button of mouse */
register int etype; /* event type byte */
register int event; /* encoded mouse event */
int mousecol; /* current mouse column */
int mouserow; /* current mouse row */
int sstate; /* current shift key status */
int newbut; /* new state of the mouse buttons */
MOUEVENTINFO mouse_event; /* info about a mouse event */
MOUQUEINFO mouse_queue; /* holds info about the mouse queue */
USHORT wait_flag; /* wait flag for read mouse queue call */
KBDINFO kbd_info; /* keyboard information */
/* is there a mouse event queued up? */
MouGetNumQueEl(&mouse_queue, mouse_handle);
if (mouse_queue.cEvents == 0)
return(FALSE);
/* get the current mouse event */
wait_flag = MOU_WAIT;
MouReadEventQue(&mouse_event, &wait_flag, mouse_handle);
/* build a simple bit field out of OS/2's rather complex one */
newbut = 0;
if (mouse_event.fs & MOUSE_BN1_DOWN)
newbut |= 1;
if (mouse_event.fs & MOUSE_MOTION_WITH_BN1_DOWN)
newbut |= 1;
if (mouse_event.fs & MOUSE_BN2_DOWN)
newbut |= 2;
if (mouse_event.fs & MOUSE_MOTION_WITH_BN2_DOWN)
newbut |= 2;
if (mouse_event.fs & MOUSE_BN3_DOWN)
newbut |= 4;
if (mouse_event.fs & MOUSE_MOTION_WITH_BN3_DOWN)
newbut |= 4;
/* check to see if any mouse buttons are different */
mousecol = mouse_event.col;
mouserow = mouse_event.row;
/* only notice changes */
if ((oldbut == newbut) && (mousecol == oldcol)
&& (mouserow == oldrow))
return(FALSE);
/* get the shift key status as well */
KbdGetStatus(&kbd_info, 0);
etype = MOUS >> 8;
sstate = kbd_info.fsState;
if (sstate & (RIGHTSHIFT | LEFTSHIFT)) /* shifted */
etype |= (SHFT >> 8);
else if (sstate & CONTROL) /* controled? */
etype |= (CTRL >> 8);
/* no buttons changes */
if (oldbut == newbut) {
/* generate a mouse movement */
if (((mouse_move == 1) && (mmove_flag == TRUE)) ||
(mouse_move == 2)) {
in_put(0);
in_put(etype);
in_put(mousecol);
in_put(mouserow);
in_put('m');
}
oldcol = mousecol;
oldrow = mouserow;
return(TRUE);
}
/* only on screen presses are legit! */
if (mousecol < 0)
mousecol = 0;
if (mouserow < 0)
mouserow = 0;
for (k = 1; k != (1 << nbuttons); k = k << 1) {
/* For each button on the mouse */
if ((oldbut&k) != (newbut&k)) {
/* This button changed, generate an event */
in_put(0);
in_put(etype);
in_put(mousecol);
in_put(mouserow);
event = ((newbut&k) ? 0 : 1); /* up or down? */
if (k == 2) /* center button? */
event += 4;
if (k == 4) /* right button? */
event += 2;
event += 'a'; /* plain */
in_put(event);
oldbut = newbut;
oldcol = mousecol;
oldrow = mouserow;
return(TRUE);
}
}
return(TRUE);
}
#endif
#if TYPEAH
/*----------------------------------------------------------------------*/
/* typahead() */
/* Returns true if a key has been pressed. */
/*----------------------------------------------------------------------*/
PASCAL NEAR typahead()
{
KBDKEYINFO kbdinfo;
KbdPeek(&kbdinfo, 0);
return(kbdinfo.fbStatus != 0);
}
#endif
/*----------------------------------------------------------------------*/
/* os2putc() */
/* Put a character at the current position in the current colors. */
/* Note that this does not behave the same as putc() or VioWrtTTy(). */
/* This routine does nothing with returns and linefeeds. For backspace */
/* it puts a space in the previous column and moves the cursor to the */
/* previous column. For all other characters, it will display the */
/* graphic representation of the character and put the cursor in the */
/* next column (even if that is off the screen. In practice this isn't */
/* a problem. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2putc(int c)
{
USHORT cell;
USHORT i;
if (c == '\n' || c == '\r') { /* returns and linefeeds */
return;
}
if (c == '\b') { /* backspace */
cell = ' ' | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
--os2col; /* move cursor back */
i = os2row * term.t_ncol + os2col;
}
else {
cell = (0x00ff & c) | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
i = os2row * term.t_ncol + os2col;
++os2col; /* move cursor forward */
}
lvb[i] = cell;
if (i < lvbMin)
lvbMin = i;
if (i > lvbMax)
lvbMax = i;
}
/*----------------------------------------------------------------------*/
/* os2eeol() */
/* Erase to end of line. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2eeol()
{
USHORT cell = ' ';
USHORT i;
cell |= (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
i = os2row * term.t_ncol + os2col; /* current cursor position */
if (i < lvbMin)
lvbMin = i;
while (i < os2row * term.t_ncol + term.t_ncol)
lvb[ i++] = cell;
if (--i > lvbMax)
lvbMax = i;
}
/*----------------------------------------------------------------------*/
/* os2eeop() */
/* Erase to end of page. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2eeop()
{
USHORT cell = ' ';
USHORT i;
#if COLOR
if (dtype != CDMONO)
cell |= (ctrans[gbcolor] << 4 | ctrans[gfcolor]) << 8;
else
cell |= 0x0700;
#else
cell |= 0x0700;
#endif
i = os2row * term.t_ncol + os2col; /* current cursor position */
if (i < lvbMin)
lvbMin = i;
while (i < term.t_nrow * term.t_ncol + term.t_ncol)
lvb[ i++] = cell;
if (--i > lvbMax)
lvbMax = i;
}
/*----------------------------------------------------------------------*/
/* os2rev() */
/* Change reverse video state. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2rev(state)
int state; /* TRUE = reverse, FALSE = normal */
{
revflag = state;
}
/*----------------------------------------------------------------------*/
/* os2cres() */
/* Change the screen resolution. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2cres(char *res) /* name of desired video mode */
{
USHORT err;
int type; /* video mode type */
VIOMODEINFO vioModeInfo;
vioModeInfo = initial.vioModeInfo;
/* From the name, find the type of video mode. */
for (type = 0; type < NDRIVE; type++) {
if (strcmp(res, drvname[type]) == 0)
break;
}
if (type == NDRIVE)
return(FALSE); /* not a mode we know about */
switch (type) {
case CDMONO:
case CDCGA:
vioModeInfo.row = 25;
break;
case CDEGA:
vioModeInfo.row = 43;
break;
case CDVGA:
vioModeInfo.row = 50;
break;
}
if (VioSetMode(&vioModeInfo, 0)) /* change modes */
return(FALSE); /* couldn't do it */
newsize(TRUE, vioModeInfo.row);
/* reset the $sres environment variable */
strcpy(sres, drvname[type]);
dtype = type; /* set the current mode */
return TRUE;
}
/*----------------------------------------------------------------------*/
/* spal() */
/* Change pallette settings. (Does nothing.) */
/*----------------------------------------------------------------------*/
PASCAL NEAR spal(char *dummy)
{
}
/*----------------------------------------------------------------------*/
/* os2beep() */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2beep()
{
DosBeep(1200, 175);
}
/*----------------------------------------------------------------------*/
/* os2open() */
/* Find out what kind of video adapter we have and the current video */
/* mode. Even if the adapter supports a higher resolution mode than is */
/* in use, we still use the current mode. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2open()
{
#if MOUSE
PTRLOC mouse_pos; /* position to place mouse */
USHORT event_mask; /* event mask for mouse handling */
#endif
initial.vioConfigInfo.cb = 0x0A;
VioGetConfig(0, &initial.vioConfigInfo, 0);
switch (initial.vioConfigInfo.adapter) {
case DISPLAY_VGA:
dtype = CDVGA;
break;
case DISPLAY_EGA:
dtype = CDEGA;
break;
case DISPLAY_CGA:
case 8: /* some new mode in OS/2 2.0 */
dtype = CDCGA;
break;
case DISPLAY_MONOCHROME:
default:
dtype = CDMONO;
}
strcpy(sres, drvname[dtype]);
initial.vioModeInfo.cb = 0x0E;
VioGetMode(&initial.vioModeInfo, 0);
newsize(TRUE, initial.vioModeInfo.row);
VioGetAnsi(&initial.ansiState, 0);
VioGetBuf((PULONG)&lvb, &lvbLen, 0);
lvbMin = lvbLen;
lvbMax = 0;
revexist = TRUE;
revflag = FALSE;
/* initialize our character input queue */
in_init();
strcpy(os, "OS2");
#if MOUSE
/* find out if we have a mouse */
if (MouOpen((PSZ)0, &mouse_handle) != 0) {
mexist = FALSE;
return;
}
/* find out some info about the mouse */
mexist = TRUE;
MouGetNumButtons(&nbuttons, mouse_handle);
/* tell it what events were interested in */
/* event_mask = MOUSE_BN1_DOWN | MOUSE_BN2_DOWN | MOUSE_BN3_DOWN;*/
event_mask = 0xff;
MouSetEventMask(&event_mask, mouse_handle);
/* get the mouse in the upper right corner */
oldrow = mouse_pos.row = 0; /* top row of display */
oldcol = mouse_pos.col = (term.t_ncol - 1); /* last col of display */
MouSetPtrPos(&mouse_pos, mouse_handle);
#else
mexist = FALSE;
#endif
}
/*----------------------------------------------------------------------*/
/* os2close() */
/* Restore the original video settings. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2close()
{
#if MOUSE
/* close our use of the mouse */
if (mexist)
MouClose(mouse_handle);
#endif
VioSetAnsi(initial.ansiState, 0);
VioSetMode(&initial.vioModeInfo, 0);
VioSetCurPos(initial.vioModeInfo.row - 1,
initial.vioModeInfo.col - 1, 0);
}
/*----------------------------------------------------------------------*/
/* os2kopen() */
/* Open the keyboard. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2kopen()
{
KBDINFO kbdInfo;
initial.kbdInfo.cb = 0x000A;
KbdGetStatus(&initial.kbdInfo, 0);
kbdInfo = initial.kbdInfo;
kbdInfo.fsMask &= ~0x0001; /* not echo on */
kbdInfo.fsMask |= 0x0002; /* echo off */
kbdInfo.fsMask &= ~0x0008; /* cooked mode off */
kbdInfo.fsMask |= 0x0004; /* raw mode */
kbdInfo.fsMask &= ~0x0100; /* shift report off */
KbdSetStatus(&kbdInfo, 0);
}
/*----------------------------------------------------------------------*/
/* os2kclose() */
/* Close the keyboard. */
/*----------------------------------------------------------------------*/
PASCAL NEAR os2kclose()
{
KbdSetStatus(&initial.kbdInfo, 0); /* restore original state */
}
#if FLABEL
PASCAL NEAR fnclabel(f, n) /* label a function key */
int f,n; /* default flag, numeric argument [unused] */
{
/* on machines with no function keys...don't bother */
return(TRUE);
}
#endif
#if 0
/*----------------------------------------------------------------------*/
/* scwrite() */
/* Write a line to the screen.
/* I tried using this routine with MEMMAP = 1, but there were too many */
/* problems with the cursor and flushing the buffer. */
/*----------------------------------------------------------------------*/
scwrite(
int row, /* row of screen to place outstr on */
char *outstr,/* string to write out (must be term.t_ncol long) */
int forg, /* foreground color of string to write */
int bacg, /* background color */
{
USHORT attr;
int i;
attr = (((ctrans[bacg] & 15) << 4) | (forg & 15)) << 8;
for (i = row * term.t_ncol; i < (row + 1) * term.t_ncol; i++)
lvb[i] = attr | *(outstr++);
if (i < lvbMin)
lvbMin = i;
if (i > lvbMax)
lvbMax = i;
}
#endif
#endif